package com.sunday.common.core.remoting.base.page;

import com.sunday.common.core.utils.ReflectToJsonUtils;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * base 简单分页模型 DTO
 *
 * @author zsy
 * @since 2022/10/13
 */
@Data
@NoArgsConstructor
public abstract class BasePage<T> implements Serializable {

    /**
     * **********************************************************
     * 查询请求参数
     * **********************************************************
     */
    /**
     * 当前页
     */
    @Schema(description = "当前页")
    private long current = 1;
    /**
     * 每页显示条数，默认 10
     */
    @Schema(description = "每页显示条数，默认 10")
    private long pageSize = 10;
    /**
     * 排序字段信息
     */
    @Schema(description = "排序字段信息")
    private List<OrderItemDTO> orders = new ArrayList<>();

    /**
     * **********************************************************
     * 查询响应参数
     * **********************************************************
     */
    /**
     * 查询数据列表
     */
    @Schema(description = "查询数据列表")
    private List<T> records = Collections.emptyList();
    /**
     * 总数
     */
    @Schema(description = "总数")
    private long total = 0;
    /**
     * 当前分页总页数
     */
    @Schema(description = "当前分页总页数")
    private long pages = 0;

    /**
     * 分页构造函数
     *
     * @param current  当前页
     * @param pageSize 每页显示条数
     */
    public BasePage(long current, long pageSize) {
        this(current, pageSize, 0);
    }

    public BasePage(long current, long pageSize, long total) {
        if (current > 1) {
            this.current = current;
        }
        this.pageSize = pageSize;
        this.total = total;
    }

    /**
     * 排序条件可以使用工厂
     *
     * @param items 排序条件
     * @return {@link BasePage <T>} 返回分页参数本身
     */
    public BasePage<T> addOrder(OrderItemDTO... items) {
        orders.addAll(Arrays.asList(items));
        return this;
    }

    /**
     * 排序条件可以使用工厂
     *
     * @param items 排序条件
     * @return {@link BasePage <T>} 返回分页参数本身
     */
    public BasePage<T> addOrder(List<OrderItemDTO> items) {
        orders.addAll(items);
        return this;
    }

    /**
     * 是否存在上一页
     *
     * @return {@link boolean}
     */
    public boolean hasPrevious() {
        return this.current > 1;
    }

    /**
     * 是否存在下一页
     *
     * @return {@link boolean}
     */
    public boolean hasNext() {
        return this.current < this.getPages();
    }

    /**
     * 当前分页总页数
     *
     * @return {@link long}
     */
    public long getPages() {
        if (getPageSize() == 0) {
            return 0L;
        }
        long pages = getTotal() / getPageSize();
        if (getTotal() % getPageSize() != 0) {
            pages++;
        }
        return pages;
    }

    @Override
    public String toString() {
        return ReflectToJsonUtils.toJson(this);
    }
}
